/**
 * 
 */
package com.cplsystems.incidencias.app.utils;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import org.zkoss.image.AImage;
import org.zkoss.image.Image;

/**
 * @author César Palalía López (csr.plz@aisa-automation.com)
 * 
 */
public class ImageUtils {

	private static synchronized BufferedImage resizeImage(
			final byte[] imageData, final int width, final int height,
			final String imageFormat) {

		ImageIcon imageIcon = new ImageIcon(imageData);
		int typeToUse = BufferedImage.TYPE_INT_ARGB;
		if (IncidenciasConstants.PNG_FORMAT.equals(imageFormat)) {
			typeToUse = BufferedImage.TYPE_4BYTE_ABGR;
		}
		BufferedImage resizedImage = new BufferedImage(width, height, typeToUse);
		Graphics2D g = resizedImage.createGraphics();
		g.setComposite(AlphaComposite.Src);
		g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g.setRenderingHint(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		g.drawImage(imageIcon.getImage(), 0, 0, width, height, null);
		g.dispose();
		return resizedImage;
	}

	private static synchronized BufferedImage scaleImage(
			final byte[] imageData, final int maxWidth, final int maxHeight,
			final String imageFormat) throws IOException {

		BufferedImage toResize = getImage(imageData);
		int typeToUse = BufferedImage.TYPE_INT_ARGB;
		if (IncidenciasConstants.PNG_FORMAT.equals(imageFormat)) {
			typeToUse = BufferedImage.TYPE_4BYTE_ABGR;
		}
		int currentWidth = toResize.getWidth();
		int currentHeight = toResize.getHeight();
		double scaleX = (double) maxWidth / (double) currentWidth;
		double scaleY = (double) maxHeight / (double) currentHeight;
		double scaleFactor = Math.min(scaleX, scaleY);

		BufferedImage toReturn = new BufferedImage(maxWidth, maxHeight,
				typeToUse);
		AffineTransform at = new AffineTransform();
		at.scale(scaleFactor, scaleFactor);
		AffineTransformOp scaleOp = new AffineTransformOp(at,
				AffineTransformOp.TYPE_BILINEAR);
		toReturn = scaleOp.filter(toResize, toReturn);
		return toReturn;
	}

	private static synchronized BufferedImage getImage(byte[] data)
			throws IOException {
		BufferedImage bi = null;
		ByteArrayInputStream bais = new ByteArrayInputStream(data);
		bi = ImageIO.read(bais);
		return bi;
	}

	private static synchronized org.zkoss.zul.Image createFromBufferedImage(
			final BufferedImage bufImage) {
		org.zkoss.zul.Image toReturn = new org.zkoss.zul.Image();
		toReturn.setContent(bufImage);
		return toReturn;
	}

	public static synchronized org.zkoss.zul.Image resize(
			final byte[] imageData, final int width, final int height,
			final String imageFormat) {

		if (imageData == null) {
			return new org.zkoss.zul.Image();
		}
		return createFromBufferedImage(resizeImage(imageData, width, height,
				imageFormat));
	}

	public static synchronized org.zkoss.zul.Image scaleToSize(
			final byte[] imageData, final int maxWidth, final int maxHeight,
			final String imageFormat) throws IOException {

		if (imageData == null) {
			return new org.zkoss.zul.Image();
		}
		return createFromBufferedImage(scaleImage(imageData, maxWidth,
				maxHeight, imageFormat));
	}

	public static synchronized byte[] getBytesFromImage(final ImageIcon image) {

		return null;
	}

	public static synchronized Image getImageFromClassResource(
			final String imageName) throws IOException {

		ClassLoader cl = ImageUtils.class.getClassLoader();
		org.zkoss.zul.Image imageToSend = new org.zkoss.zul.Image();
		imageToSend.setContent(new AImage(cl.getResource(imageName)));
		return imageToSend.getContent();
	}

}
